home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 6
/
QRZ Ham Radio Callsign Database - Volume 6.iso
/
mac
/
files
/
amiga
/
csrc720j.lzh
/
mb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-20
|
16KB
|
754 lines
/*
* MB.C - 9/20/92 - MailBox mainline code.
*/
/*
* Copyright (C) 1987, 1988
* On Modules by H. N. Oredson
* Copyright (C) 1988, 1989, 1990, 1991, 1992
* By the CBBS Group.
*
* It is being developed by the CBBS Group.
* It may be freely copied for non-commercial use,
* as long as this notice is retained.
*
* This notice and Copyright apply to all modules
* referenced by this module.
*
*/
#include "mb.h"
#ifdef MCH_AMIGA
extern char conn_direction;
#ifndef MCH_SYSOP
extern PORTS *devtnc;
#endif
#include "lock.h"
/* Allow user to specify the device name and unit number if they have
a multi-serial card. But default it to the standard device on unit zero
If ser_dev_name is zero then ser.c will use the standard name.
*/
char *ser_dev_name = 0L;
long unit = -1L;
extern short kambbs, thebox, debug , tapr_flag;
long BaudRate;
short left = 0, top = 0, width = 640, height = 256;
extern int daylight;
#else
char *ver = "\nC-BBS V7.2, 20 SEP 1992\n\n";
char *vers = "[CBBS-7.20-H$]\n";
#endif
char *nullstr = "";
PORTS *porthd = NULL;
PORTS *cport = NULL;
PORTS *port;
int scrmax, dirmax, log_mon;
TMP *tmp;
MLM *motd;
char *helpfile, *infofile;
char *bbmenu, *symenu, *rmenus, *mumsg;
char *reqmsg, *qth, *keylst;
char *mcant, *mdone, *mfind, *mexst, *mnfile, *mnmsg;
char *mprot, *mtime, *mwhat, *mnport, *mndir, *minuse;
char achar, rchar, tchar, wchar;
word s_param, p_window, c_flag, b_flag;
byte s_mart, s_prompt, s_flag, unt_hr;
char scmd[24];
#ifdef MCH_AMIGA
#ifndef MCH_SYSOP
char hostport = 'A';
#else
char hostport = '1';
#endif
#endif
#ifdef MCH_AMIGA
short timezone = -900; /* Initialize to impossible number of minutes */
extern char tmpstr[];
#endif
main(argc, argv)
int argc;
char *argv[];
{
#ifdef MCH_AMIGA
char *cp;
short i;
/* Might as well do a quick check to make sure the locker is there.
*/
if(FindPort((UBYTE *)LOCK_NAME) == 0L) {
printf("Can't find the locker process\n");
exit(10);
}
/* Get the environment variable timezone if it is set.
Doing it here allows the user to override the value of TZ_CHU
with the -z argument.
*/
timezone = gettz("");
get_reject();
while(argc > 1) {
if(argv[1][0] == '-') {
switch(tolower(argv[1][1])) {
/* allow user to specify the position of the window on the screen
-wL/T/W/H
*/
case 'w':
cp = &argv[1][2];
left = atoi(cp);
while(*cp && (*cp != '/'))cp++;
if(*cp == 0)break;
cp++;
top = atoi(cp);
while(*cp && (*cp != '/'))cp++;
if(*cp == 0)break;
cp++;
width = atoi(cp);
while(*cp && (*cp != '/'))cp++;
if(*cp == 0)break;
cp++;
height = atoi(cp);
setwindow(left,top,width,height);
break;
/* In multi mode, specify the port which this copy will open
*/
case 'p':
hostport = toupper(argv[1][2]);
break;
case 'n': /* Serial port name for multi-serial users */
ser_dev_name = &argv[1][2];
break;
case 'u': /* Serial port unit number for multi-serial */
unit = (long)atoi(&argv[1][2]);
break;
case 'd':
debug = 1;
break;
/* Baud rate is in the host driver */
case 'b':
BaudRate = atol(&argv[1][2]);
break;
case 't':
/* tell serial read routine to strip high bit off all bytes
read from the TNC because it is a TAPR upgrade kit that
generates NO parity only with the parity bit forced to one
*/
tapr_flag++;
break;
case 'z':
/* Specify the timezone so that you can keep your amiga
on your local time but have the time in messages converted
to UTC. format is -z[-]hh[:mm][d]
Times WEST of Greenwich are POSITIVE.
Times EAST of Greenwich are NEgative.
The optional minutes ":mm" allows places like Newfoundland
to specify their zone as 3:30.
If the optional letter 'd' is present at the end of the
string, then your local time zone is adjusted for daylight
savings time.
The -z argument, if set, overrides any value in the TZ_CHU
environment variable.
*/
timezone = gettz(&argv[1][2]);
break;
}
argc--;
argv++;
continue;
}
break;
}
/* Just make sure that there isn't already a port with our name on it */
if(testport()) {
exit(1);
}
/* Call routine that reads my modified init() so that the config.mb
file is opened early to permit options in config.mb to be read
before the window and serial port are opened. This allows options
to be used that affect the opening of the window or serial parameters.
*/
if (argc > 1)i = setinit(argv[1]); else i = setinit("config.mb");
if(i)exit(1);
printf("Serial device name = %s unit = %ld\n",ser_dev_name,unit);
if(initser()) {
printf("error opening serial port\n");
exit(1);
}
if(openterm()) {
printf("error opening terminal\n");
cleanser();
exit(1);
}
if(inittimer()) {
printf("error opening timer\n");
cleanser();
closeterm();
exit(1);
}
/* This does more than the quick check at the beginning of main() so
don't remove this call.
*/
if(i = findlock()) {
printf("Can't find the Lock process - %d\n",i);
cleanser();
closeterm();
exit(1);
}
/* This allows the port driver to count how many processes are running
without having to be told
*/
setbusy();
/* Up to this point all routines MUST do their own cleaning up and then
exit() directly. AFTER setbusy() has been called any further errors
should cause done() to be called because done() calls clrbusy.
Otherwise the locking program will have an incorrect count of the number
of active processes.
The EXCEPTION to this rule is inittnc() which already cleared up its
own mess, so I just added a clrbusy as well, rather than try to fix
it up to use done().
*/
#endif
if (argc > 1) init(argv[1]); else init("config.mb");
#ifdef MCH_AMIGA
/* Compute the first Sunday in April and last Sunday in October
if daylight savings is being used.
*/
dstdates();
if(timezone != -900) {
i = timezone;
sprintf(tmpstr,"Timezone = %c%d:%02d %s\n",
i<0?'-':' ',i<0?-i/60:i/60,i<0?(-i)%60:i%60,
daylight?"(DST)":"");
ttputs(tmpstr);
printf("%s",tmpstr);
i = dst(timezone);
if(i != timezone) {
sprintf(tmpstr,"DST time = %c%d:%02d\n",
i<0?'-':' ',i<0?-i/60:i/60,i<0?(-i)%60:i%60);
ttputs(tmpstr);
printf("%s",tmpstr);
}
}
else {
cp = "Timezone not set - Assume UTC and no DST\n";
printf("%s",cp);
ttputs(cp);
timezone = 0;
daylight = 0;
}
#endif
#ifdef MCH_AMIGA
/* Open up the AREXX public port so that the waitport program can be used
to start up several CBBS copies in sequence and also allows communication
from outside processes and between multiple 'mb' processes.
*/
if(open_rexx())done(1);
#endif
while (true)
{
s_mart = 0;
#ifdef MCH_AMIGA
kambbs = 0;
thebox = 0;
conn_direction = ' ';
user_title("");
titles();
#endif
do_idle();
setbusy();
login();
#ifndef MCH_AMIGA
if (!(port->mode & exclude)) do_cmds();
#else
/*FIX 8 ignore idle terminal caused by monitoring data that looks like a
"*** CONNected" message.
*/
if(!(port->mode & idle)) {
if(!(port->mode & exclude)) do_cmds();
}
#endif
logo();
}
}
do_cmds()
{
register PORTS *p;
register char *i, *o;
p = port;
while(true)
{
prompt();
getcmd();
if (p->mode & gone) return;
/*
* Console broke in on a user?
*/
if (p->flags & p_opreq)
{
p->flags clrbit p_opreq;
prtx(talkm1);
if (p->tmode)
{
cmdtnc();
convtnc();
}
ioport(cport);
prtx(mumsg);
cport->fl = NULL;
term(p);
ioport(p);
tncstate();
if (p->tmode) trantnc(); else convtnc();
if (p->mode & gone) return;
}
/*
* Check for LINK.
* Require "LINKED to" to be first command.
*/
else if (islink(p->line))
{
if (p->cmdcnt) p->msg = mwhat; else
{
strcpy(p->line, p->line + 14);
logina(true);
remnl(p->line);
log('C', 'L', ' ', p->line);
if (p->mode & exclude) return;
}
}
/*
* Must be a command.
*/
else
{
docmd();
if (p->errors > p->errmax) p->mode = forced;
if (p->mode & (gone | idle | logout)) return;
}
}
}
/*
* Q command: exit to DOS.
*/
#ifndef MCH_AMIGA
done()
{
byte pflg;
if (sure()) return;
#else
extern short done_flag;
done(askflag)
int askflag;
{
byte pflg;
if(!askflag && sure()) return;
done_flag = 0;
cursor_off();
close_rexx();
#endif
upduser(cport->user);
log('X', 'Q', ' ', nullstr);
clslog();
clsusr();
clsmsg();
clsmon();
iooff();
clrbusy();
pflg = getp_flag();
putp_flag(pflg clrbit p_window);
#ifdef MCH_AMIGA
endtimer();
cleanser();
freefcb();
closeterm();
stoplock();
#endif
exit(0);
}
/*
* Give the user a prompt.
*/
prompt()
{
register PORTS *p, *tp;
p = port;
if (p->msg isnt NULL) prtx(p->msg);
p->msg = NULL;
/*
* Tell sysop who this is.
*/
if (p isnt cport) { ioport(cport); prtx(mumsg); ioport(p); }
/*
* Show any connect request seen on the user port.
*/
if (p->flags & p_req) prtx(reqmsg);
p->flags clrbit p_req;
/*
* Bleed off any connect requests on other ports.
*/
/* There aren't any other ports on the AMIGA */
#ifndef MCH_AMIGA
for (tp = porthd; tp isnt NULL; tp = tp->next) if (tp->mode & idle)
if ((tp->dev is p_tnc) and (tp isnt p))
{
ioport(tp);
while (instat()) getdat();
}
ioport(p);
#endif
/*
* Display the prompt.
*/
curtim();
switch (p->mode)
{
case local :
case sysop :
prtx(symenu);
break;
case remote:
if (!(p->user->options & u_bbs))
{
if (s_prompt & s_p_name) if (!(p->user->state & u_name)) prtx(um[4]);
if (s_prompt & s_p_home) if (!(p->user->state & u_home)) prtx(um[5]);
if (s_prompt & s_p_zip) if (!(p->user->state & u_zip)) prtx(um[6]);
if (s_prompt & s_p_qth) if (!(p->user->state & u_qth)) prtx(um[7]);
}
#ifndef MCH_AMIGA
if (p->user->options & (u_bbs | u_expert)) prtx(bbmenu); else prtx(rmenus);
#else
if(p->user->options & u_bbs) outstr(">\n");
else if (p->user->options & u_expert) prtx(bbmenu);
else prtx(rmenus);
#endif
break;
}
}
/*
* Log the user off.
* Do any defered remote sysop command.
*/
logo()
{
register PORTS *p;
register PORTS *tp;
register char t;
p = port;
switch(p->mode)
{
case idle : t = 'A'; break; /* Init bbs logout */
case logout : t = 'B'; break;
case discon : t = 'D'; break;
case exclude: t = 'E'; break;
case forced : t = 'F'; distnc(); break;
case timeout: t = 'T'; prtx(mtime); break;
default : t = '?'; break;
}
#ifndef MCH_AMIGA
log('X', t, ' ', nullstr);
#else
log('X', t, port->id , nullstr);
#endif
/*
* If any port was used in terminal mode by the console,
* disconnect it.
*/
if (p->dev is p_console)
for (tp = porthd; tp isnt NULL; tp = tp->next)
if (tp->flags & p_term)
{
ioport(tp);
tp->mode = remote;
distnc();
tp->mode = idle;
tp->flags clrbit p_term;
}
ioport(p);
/*
* Change TNC back to "standard" if was in "sysop" mode.
* May have just THOUGHT we discon, REALLY disconnect.
*/
if (p->dev is p_tnc)
{
if (p->flags & p_clrsys) mkrem();
p->mode = remote;
distnc();
}
if (p->dev is p_serial) p->flags clrbit p_trans;
#ifdef MCH_AMIGA
if (p->dev is p_nulmdm) p->flags clrbit p_trans;
#endif
#ifndef MCH_SYSOP
/* Hang up a modem */
if(p->dev is p_serial) {
force_modem();
}
/* If it was the console but the serial device is a modem, then allow
phone to ring again.
*/
if(p->dev is p_console) {
if(devtnc->dev is p_serial) {
tp = p;
ioport(devtnc);
outstr("ATS0=2\n");
waitcmd(2);
ioport(tp);
}
}
#endif
p->mode = idle;
upduser(p->user);
/*
* If there was a "defered remote sysop command" do it.
*/
ioport(cport);
if (s_param & s_cmd)
{
s_param clrbit s_cmd;
strcpy(cport->line, scmd);
parse();
wait(10); /* Give sysop chance to get HIS system online */
cport->mode = local; /* Do command as if console did it */
docmd();
cport->mode = idle;
}
clnlog();
clsusr();
setfwd();
clsmsg();
}
/*
* MailBox is idle.
* See if there is anything to do, and do it.
* If nothing to do, wait for connect.
*/
#ifndef MCH_AMIGA
do_idle()
{
register PORTS *p;
register short curmin, lastmin, curmon;
for (p = porthd; p isnt NULL; p = p->next) p->ec = p->ecmon;
getc_flag();
if (c_flag & p_window) acmd();
allon(); /* Turn on monitoring and connects */
clrbusy();
curtim();
curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
while(true)
{
/*
* Check the port command flag to see if another window has
* issued a command request. If so setup and do the command.
*/
getc_flag();
if (c_flag & p_window)
{
setbusy();
alloff();
acmd();
allon();
clrbusy();
}
lastmin = curmin;
curtim();
curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
/*
* Once each minute:
* Forward now, if it is time on any port.
*/
if (curmin isnt lastmin) afwd(curmin);
if (s_param & s_log_on) if (curmon isnt log_mon) chglog();
/*
* Look for a login.
*/
for (p = porthd; p isnt NULL; p = p->next)
{
ioport(p);
if (instat()) switch(p->dev)
{
case p_serial:
p->flags clrbit p_give;
getdat();
p->flags setbit p_give;
if (iscon(p->line)) return;
break;
case p_tnc:
p->flags clrbit p_give;
getdat();
p->flags setbit p_give;
if (iscon(p->line)) return;
monitor();
break;
case p_console:
if (inchar() is wchar) return;
break;
}
p->flags setbit p_give;
}
}
}
#endif
/*
* Do commands retrieved from the bios.
*/
#ifndef MCH_AMIGA
acmd()
{
char need_msg = false;
char notime = false;
port->mode = local;
getcomd();
if (s_flag & s_dv) begin_lock();
if (isdigit(port->opt2))
{
notime = true;
port->opt2 = port->opt2 ^ 0x70;
}
if ((port->opt1 is 'X') and (findport(port->opt2)))
{
if (notime) port->opt2 = ' '; else port->opt2 = 'I';
readmsg();
readusr();
need_msg = true;
}
getc_flag();
putc_flag( c_flag clrbit p_window);
if (s_flag & s_dv) end_lock();
if (need_msg or (port->opt2 is 'H'))
{
sprintf(port->line, "%c%c", port->opt1, port->opt2);
parse();
docmd();
}
if (need_msg)
{
clnlog();
setfwd();
clsmsg();
clsusr();
}
port->mode = idle;
}
#endif
#ifdef MCH_AMIGA
#ifndef MCH_SYSOP
acmd()
{
char need_msg = false;
char notime = false;
port->mode = local;
if (s_flag & s_dv) begin_lock();
if(port->opt1 == 'X')
{
readmsg();
readusr();
need_msg = true;
}
if (s_flag & s_dv) end_lock();
if (need_msg or (port->opt2 is 'H'))
{
sprintf(port->line, "%c%c", port->opt1, port->opt2);
parse();
docmd();
}
if (need_msg)
{
clnlog();
setfwd();
clsmsg();
clsusr();
}
port->mode = idle;
}
#endif
#endif
/* Bring this here from mbfwd to save having to make a separate sysop
version of mbfwd (Otherwise it could stay there)
*/
#ifdef MCH_SYSOP
all_fwd()
{
word pflg;
port->opt1 = 'X';
putcomd( port->opt1, port->opt2 );
#ifndef MCH_AMIGA
pflg = getp_flag();
putc_flag (pflg);
#endif
port->mode = logout;
}
#endif